package com.leung.mybatis.binding;


import cn.hutool.core.lang.ClassScanner;
import com.leung.mybatis.session.SqlSession;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author 丨一
 * @version 1.0
 * @title MapperRegistry
 * @description: 映射注册机
 * @date 2025/10/8 上午10:46
 */
public class MapperRegistry {

    //将已经添加的映射器代理加入到 hashMap
    public final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<>();

    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);

        if (null == mapperProxyFactory) {
            throw new RuntimeException("Type: " + type + "is not exist");
        }

        try {
            return mapperProxyFactory.newInstance(sqlSession);
        } catch (Exception e) {
            throw new RuntimeException("Error getting mapper instance. Cause:" + e, e);
        }
    }

    public <T> void addMapper(Class<T> type) {
        if (type.isInterface()) {
            if (hasMapper(type)) {
                throw new RuntimeException("Type : " + type + "is already exist");
            }
        }

        //注册映射器代理工厂
        knownMappers.put(type, new MapperProxyFactory<T>(type));
    }


    private <T> boolean hasMapper(Class<T> type) {
        return knownMappers.containsKey(type);
    }

    public void addMappers(String packageName) {
        Set<Class<?>> mapperSet = ClassScanner.scanPackage(packageName);
        for (Class<?> mapperClass : mapperSet) {
            addMapper(mapperClass);
        }
    }
}
